/**
 * 
 */
package com.budingge.common.ftputils;

import java.io.IOException;
import java.net.SocketException;
import java.net.URL;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;


/**
 * FTPClient操作，负责配置创建FTPClient连接
 * @author budingge.com
 *
 */
public class FTPClientHelper {
	private FtpClientCfg clientCfg;
	private FTPClient ftpClient;
	public FTPClientHelper(FtpClientCfg clientCfg) throws Exception {
		super();
		this.clientCfg = clientCfg;
		reconnectServer();
	}
	
	public FtpClientCfg getClientCfg() {
		return clientCfg;
	}


	public void setClientCfg(FtpClientCfg clientCfg) {
		this.clientCfg = clientCfg;
	}


	public FTPClient getFtpClient() {
		return ftpClient;
	}

	public void setFtpClient(FTPClient ftpClient) {
		this.ftpClient = ftpClient;
	}

	public FTPClientHelper() {
		super();
	}


	public boolean reconnectServer() throws Exception {
		disconnectServer();
		return connectServer(clientCfg.server, clientCfg.port, clientCfg.user,
				clientCfg.password, clientCfg.path, clientCfg.conn_time_out,
				clientCfg.data_time_out, clientCfg.local_passive_mode,
				clientCfg.encoding);
	}
	
	/**
	 * 断开与远程 FTP 服务器的连接
	 * 
	 * @throws IOException
	 */
	public void disconnectServer() throws IOException {
		if (ftpClient != null && ftpClient.isConnected()) {
			ftpClient.disconnect();
		}
		//clientCfg = null;
	}
	/**
	 * 根据FTP配置连接并登录到FTP服务器
	 * 
	 * @param server
	 *            FTP 服务器地址(IP)
	 * @param port
	 *            端口号
	 * @param user
	 *            用户名
	 * @param password
	 *            密码
	 * @param path
	 *            登录后转向的FTP目录
	 * @return
	 * @throws Exception
	 * @throws SocketException
	 * @throws IOException
	 */
	public boolean connectServer(String server, int port, String user,
			String password, String path, int conn_time_out,
			int data_time_out, boolean local_passive_mode, String encoding)
			throws Exception {
		StringBuffer sb = new StringBuffer();
		sb.append("[ip:").append(server);
		sb.append(", port:").append(port);
		sb.append(", userName:").append(user);
		sb.append(", password:").append(password);
		sb.append(", workDirectory:").append(password).append("]");

		if (clientCfg == null) {
			clientCfg = new FtpClientCfg(server, port, user, password, path,
					conn_time_out, data_time_out, local_passive_mode, encoding);
		}

		boolean connectResult = false;
		try {
			ftpClient.connect(server, port);
			if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
				connectResult = ftpClient.login(user, password);
				if (connectResult) {
					ftpClient.setControlEncoding(encoding);
					ftpClient.setConnectTimeout(conn_time_out);
					ftpClient.setDataTimeout(data_time_out);
					if (local_passive_mode) {
						ftpClient.enterLocalPassiveMode();
					}
				} else {
					throw new Exception(ftpClient.getReplyString());
				}

			} else {
				ftpClient.disconnect();
			}
		} catch (Exception e) {
			throw e;
		}

		if (connectResult && path != null && path.length() > 0) {
			try {
				connectResult = ftpClient.changeWorkingDirectory(path);
			} catch (IOException e) {
				throw e;
			}
		}
		return connectResult;
	}
	
	/**
	 * 根据FTP配置连接并登录到FTP服务器
	 * 
	 * @param server
	 *            FTP 服务器地址
	 * @return
	 * @throws Exception
	 */
	public boolean connectServer(String ftp_url, int conn_time_out,
			int data_time_out) throws Exception {
		return connectServer(new URL(ftp_url), conn_time_out, data_time_out,
				true);
	}

	/**
	 * 根据FTP配置连接并登录到FTP服务器
	 * 
	 * @param server
	 *            FTP 服务器地址
	 * @return
	 * @throws Exception
	 */
	public boolean connectServer(URL url, int conn_time_out,
			int data_time_out, boolean local_passive_mode) throws Exception {

		int port = url.getPort() == -1 ? 21 : url.getPort();
		String userinfo = url.getUserInfo();
		String user = "anonymous";
		String password = "";
		if (StringUtils.isNotBlank(userinfo)) {
			String[] split = userinfo.split(":");
			user = split[0];
			password = split.length == 2 ? split[1] : "";
		}
		return connectServer(url.getHost(), port, user, password, "/",
				conn_time_out, data_time_out, local_passive_mode, "ISO-8859-1");
	}
}
